package com.ggh.handler;
import	java.util.ArrayList;
import	java.util.HashMap;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ggh.entity.*;
import com.ggh.service.RoomWinRecordService;
import com.ggh.service.RulesMoneyBeanService;
import com.ggh.service.impl.RulesMoneyBeanServiceImpl;
import com.ggh.util.ApplicationContextProvider;
import com.ggh.util.JsonUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jj
 * @date 2019/10/10 11:00
 */
@Slf4j
public class EventHandler {

    /**
     *  牌九类房间
     */
    private RoomBeanP room;
    //------------工具类-----------
    /**
     * 工具解析类
     */
    private Gson gson= JsonUtils.get();
    /**
     * 上庄，下庄操作工具类
     */
    private UserOperationP operp = new UserOperationP();
    /**
     * 游戏逻辑类
     */
    private GameService ms = new GameService();
    /**
     * 算法逻辑类
     */
    private BeginToJudgePKC pkc = new BeginToJudgePKC();
    /**
     * 相关规则
     */
    private RulesMoneyBeanService rulesMoneyBeanService= ApplicationContextProvider.getBean(RulesMoneyBeanServiceImpl.class);
    /**
     * 近几局的输赢记录
     */
    private RoomWinRecordService roomWinRecordService=ApplicationContextProvider.getBean(RoomWinRecordService.class);
    /**
     * @description :心跳检测，还有问题
     * @param user
     * @param map
     * @return: void
     * @date : 2019/10/10 13:42
     * @author : jj
     * @throws
     */
    public void xtjc(UserBean user, Map<String, Object> map ){
        log.info("--------------------------------用户:" + user.getUserid() + "，进入心跳请求");
        user.setTaskTime(5);
        map.clear();
        map.put("type", "HeartMessage");
        map.put("messages" , "");
    }
    /**
     * @description :百人牌九房间列表
     * @param user
     * @param map
     * @return: void
     * @date : 2019/10/10 15:40
     * @author : jj
     * @throws
     */
    public void baiRenPJ(UserBean user, Map<String, Object> map ){
        // 遍历房间map集合
        //存入链表
        ArrayList<RoomBeanP> list = new ArrayList();
        for (RoomBeanP roomBean : Public_State_P.roomMap.values()) {
            if (roomBean.getGame_type() < 2) {
                list.add(roomBean);
            }
        }
        //添加消息
        map.put("type", TypeBean.BaiRenPJ);
        map.put("messages", gson.toJson(list));
    }
    /**
     * @description :百人加入房间
     * @param user
     * @param map
     * @param messages
     * @return: beanSiRen.RoomBeanP
     * @date : 2019/10/11 14:05
     * @author : jj
     * @throws
     */
    public RoomBeanP joinRoom(UserBean user, Map<String, Object> map,String messages){
        /**
         * 传参问题
         */
        if (messages.isEmpty()){
            map.put("type", "MessageReceive");
            map.put("messages", "参数错误");
            return null;
        }
        /**
         *  用户不在大厅
         */
        System.out.println(user.getReady_state());
        if (user.getReady_state()!= -1) {
            map.put("type", "MessageReceive");
            map.put("messages", "您还在房间中");
            return null;
        } else {
            // 调用 创建房间方法、 执行加入房间
            HashMap<Integer, RoomBeanP> matching = ms.Matching(messages, user);
            if (matching==null){
                map.put("type", "MessageReceive");
                map.put("messages", "金币不足");
                return null;
            }
            if (matching.get(1)!=null){
                map.put("type", "MessageReceive");
                map.put("messages", "您已经存在房间中");
                return room;
            }
            room=matching.get(2);
            /**
             * 房间不存在
             * 加入(坐下)成功
             */
            if (room != null) {
                 //添加房间近20局的输赢
                List<RoomWinRecord> roomWinRecords = roomWinRecordService.roomWinRecordList(Integer.valueOf(room.getRoomno()),20);
                if (roomWinRecords==null||roomWinRecords.size()<20){
                    List<RoomWinRecord>  roomWinList=  roomWinRecordService.aList(20-roomWinRecords.size());
                    roomWinRecords.addAll(roomWinList);
                }
                List<Map<String,Integer>> userRecords=new ArrayList();
                for (RoomWinRecord rw:roomWinRecords){
                    Map<String,Integer> userMap =new HashMap();
                    userMap.put("chuWin",rw.getChuWin());
                    userMap.put("tianWin",rw.getTianWin());
                    userMap.put("moWin",rw.getMoWin());
                    userRecords.add(userMap);
                }
                room.setWinRecord(userRecords);
                map.put("type", "EnterRoom_Success");
                map.put("messages", gson.toJson(room));
                return room;
            } else {
                map.put("type", "MessageReceive");
                map.put("messages", "未知错误！！");
                map.put("stuts", "0");
                return null;
            }
        }
    }

    /**
     * 获取上庄规则
     * @param user
     * @param map
     */
    public void szgz(UserBean user, Map<String, Object> map) {
        if (room.getGame_type() > 1) {
            map.put("type", "BaiRenShangZhuangEorre");
            map.put("messages", "房间不对！！！！");
        } else {
            sendSz(user,map);
        }
    }

    /**
     * @description :百人上庄
     * @param user
     * @param map
     * @param messages
     * @return: void
     * @date : 2019/10/11 10:16
     * @author : jj
     * @throws
     */
    public void baiRenShangZhuang(UserBean user, Map<String, Object> map,Integer messages){
            //下庄金额
            user.setDqnumber(messages);
            /*上庄*/
            int i = operp.robBanker(user, room);
            map.put("type", "BaiRenShangZhuangSuccess");
            map.put("messages", gson.toJson(room));
    }
    /**
     * @description :用户下庄
     * @param user
     * @param map
     * @param messages
     * @return: void
     * @date : 2019/10/11 10:22
     * @author : jj
     * @throws
     */
    public void baiRenXiaZhuangApply(UserBean user, Map<String, Object> map,String messages){
        /*下庄*/
        if ("XiaZhuang".equals(messages)) {
            operp.downBanker(user, room);
            map.put("type", "BaiRenXiaZhuangSuccess");
            map.put("messages", gson.toJson(room));
            /*继续*/
        } else if ("Continue".equals(messages)) {
            map.put("type", "BaiRenXiaZhuangSuccess");
            map.put("messages", gson.toJson(room));
        }

    }
    /**
     * @description :百人下注
     * @param user
     * @param map
     * @param messages
     * @return: void
     * @date : 2019/10/11 12:17
     * @author : jj
     * @throws
     */
    public void baiRenXiaZhu(UserBean user, Map<String, Object> map,String messages) {
        //容器
        HashMap sl = new HashMap();
        /* 获取金额 */
        JSONObject jsonData = JSONObject.fromObject(messages);
        Integer money = Integer.valueOf(String.valueOf(jsonData.get("money")));
        String deskno = String.valueOf(jsonData.get("deskno"));
        /* 判断可下注金额 */
        if (room.getKMoney() - money >= 0) {
            room.getLock().lock();
            try {
                if (user.getMoney()-money>0) {
                    /*判断玩家下注位置 */
                    if (room.getGame_type() == 1) {
                        //如果s1等于null则是庄家不用返回
                        sl = baiRenXiaoXz(user, deskno, money, sl);
                        if (sl != null) {
                            map.put("type", "BaiRenMoneyBetsSuccess");
                            map.put("messages", gson.toJson(sl));
                        }
                    } else {
                        sl = baiRenDaXz(user, deskno, money, sl);
                        /**
                         * 创建消息结果
                         */
                        if ((Integer) sl.get("money") == 0) {
                            map.put("type", "BaiRenMoneyBetsFailed");
                            map.put("messages", "已到别的桌子，不可重复");
                        } else {
                            room.setKMoney(room.getKMoney() - money);
                            map.put("type", "BaiRenMoneyBetsSuccess");
                            map.put("messages", gson.toJson(sl));
                        }
                    }
                }else {
                    map.put("type", "BaiRenMoneyBetsFailed");
                    map.put("messages", "金币不足");
                }
            }catch (Exception e){
                System.out.println(e.toString());
            }finally {
                room.getLock().unlock();
            }
        } else {
            map.put("type", "BaiRenMoneyBetsFailed");
            map.put("messages", "已满");
            map.put("userId", user.getUserid());


        }
    }
    /**
     * @description :提示组牌
     * @param user
     * @param map
     * @return: void
     * @date : 2019/10/11 14:25
     * @author : jj
     * @throws
     */
    public  void baiRenLargeZuPaiMessage(UserBean user, Map<String, Object> map){
        List<Integer> tips = null;
            if (user.getBanker()==2){
                tips = pkc.tips(room.getZpai());
            }else if (user.getIsbrand()==1){
                tips = pkc.tips(room.getCpai());
            }else if (user.getIsbrand()==2){
                tips = pkc.tips(room.getTpai());
            }else if (user.getIsbrand()==3){
                tips = pkc.tips(room.getMpai());
            }
            if (tips!= null){
                map.put("messages", gson.toJson(tips));
            }else {
                map.put("messages", "参数错误");
            }
        map.put("type", TypeBean.BaiRenLargeZuPaiMessageSUCCESS);
    }
    /**
     * @description :用户扣牌
     * @param user
     * @param map
     * @param messages
     * @return: void
     * @date : 2019/10/11 14:39
     * @author : jj
     * @throws
     */
    public void baiRenLargeKouPaiMessage(UserBean user, Map<String, Object> map,String messages){
        // 进行排序，修改用户状态
        user.setPower_type(2);
        // 获取前端传输的牌的信息，替换牌
        String[] pai =messages.replace("[", "").replace("]", "").split(",");
        /**
         * 替换牌值
         */
        room.getLock().lock();
            if (user.getBanker()==2){
                for (int i = 0; i < room.getZpai().size(); i++) {
                    room.getZpai().set(i, Integer.valueOf(pai[i]));
                }
                map.put("messages", "Banker");
            }else if (user.getIsbrand()==1){
                for (int i = 0; i < room.getCpai().size(); i++) {
                    room.getCpai().set(i, Integer.valueOf(pai[i]));
                }
                map.put("messages", "Chu");
            }else if (user.getIsbrand()==2){
                for (int i = 0; i < room.getTpai().size(); i++) {
                    room.getTpai().set(i, Integer.valueOf(pai[i]));
                }
                map.put("messages", "Tian");
            }else if (user.getIsbrand()==3){
                for (int i = 0; i < room.getMpai().size(); i++) {
                    room.getMpai().set(i, Integer.valueOf(pai[i]));
                }
                map.put("messages", "Mo");
            }else {
                map.put("messages", "");
            }
        String brMessages=map.get("messages")+","+user.getUserid();
        map.put("messages",brMessages);
        map.put("type", "BaiRenLargeKouPaiMessageSUCCESS");
        room.getLock().unlock();
    }
    //-----------------------------------------------------四人游戏-------------------------------------------------------------------------------
    /**
     * @description :区别房间并遍历房间
     * @param user
     * @param map
     * @return: void
     * @date : 2019/10/11 15:28
     * @author : jj
     * @throws
     */
    public void siRenPj(UserBean user, Map<String, Object> map){
        /* 区分房间 */
        List list = new ArrayList();
        List listName = new ArrayList();
        listName.add("四张（50）锅");
        listName.add("四张（100）锅");
        listName.add("两张（50）锅");
        listName.add("两张（100）锅");
        listName.add("两张（200）锅");
        Map<Integer, Integer> collect = Public_State_PSiRen.roomMap.values().stream().
                collect(Collectors.groupingBy(RoomBeanP::getGame_type, Collectors.summingInt(RoomBeanP::getNumber)));
        List<Object> values =  Arrays.asList(collect.values().toArray());
        list.add(listName);
        list.add(values);
        map.put("type", "SiRenPJ");
        map.put("messages", gson.toJson(list));
    }
    /**
     * @description :选择区域
     * @param user
     * @param map
     * @param messages
     * @return: void
     * @date : 2019/10/11 15:58
     * @author : jj
     * @throws
     */
    public void siRenRoomInfo(UserBean user, Map<String, Object> map,String messages){
        List<RoomBeanP> roomBeanPList = new ArrayList<>();
        //判断客户端的选择
        for (RoomBeanP roomBeanP : Public_State_PSiRen.roomMap.values()) {
            int gameType = roomBeanP.getGame_type();
            if ("四张（50）锅".equals(messages)) {
                if (3 == gameType) {
                    roomBeanPList.add(roomBeanP);
                }
            }else if ("四张（100）锅".equals(messages)) {
                if (4 == gameType) {
                    roomBeanPList.add(roomBeanP);
                }
            }else if ("两张（50）锅".equals(messages)) {
                if (5 == gameType) {
                    roomBeanPList.add(roomBeanP);
                }
            }else if ("两张（100）锅".equals(messages)) {
                if (6 == gameType) {
                    roomBeanPList.add(roomBeanP);
                }
            }else if ("两张（200）锅".equals(messages)) {
                if (7 == gameType) {
                    roomBeanPList.add(roomBeanP);
                }
            }else {
                System.out.println("错误！！！");
            }
        }
        map.put("userId", user.getUserid());
        map.put("type", "SiRenRoomInfo");
        map.put("messages", gson.toJson(roomBeanPList));
        map.put("stuts", 0);
    }
    /**
     * @description :加入房间
     * @param user
     * @param map
     * @param messages
     * @return: beanSiRen.RoomBeanP
     * @date : 2019/10/11 17:46
     * @author : jj
     * @throws
     */
    public RoomBeanP siRenEnterRoom(UserBean user, Map<String, Object> map,String messages){
        /*用户不在大厅*/
        if (user.getReady_state() != -1) {
            map.put("type", "MessageReceive");
            map.put("messages", "您还在房间中");
            return null;
        } else {
            // 调用 创建房间方法、 执行加入房间
            HashMap<Integer, RoomBeanP> matching = ms.Matching(messages, user);
            if (matching==null){
                map.put("type", "MessageReceive");
                map.put("messages", "金币不足！！");
                return null;
            }
            if (matching.get(1)!=null){
                map.put("type", "SiRenEnterRoomSuccess");
                map.put("messages", "您已经存在房间中");
                return room;
            }
            room=matching.get(2);
            /*如果房间为null加入失败*/
            if (room != null) {
                map.put("type", "SiRenEnterRoomSuccess");
                map.put("messages", gson.toJson(room));
            } else {
                map.put("type", "MessageReceive");
                map.put("messages", "您在房间中！！");
            }
            return room;
        }
    }
    /**
     * @description 准备开始
     * @param user
     * @param map
     * @return: int
     * @date : 2019/10/12 11:02
     * @author : jj
     * @throws
     */
    public boolean siRenPlayerReady(UserBean user, Map<String, Object> map){
        if (room.getUserBean(user.getUserid()) ==null) {
            map.put("type", "SiRenPlayerReadyFailed");
            map.put("messages", "玩家" + user.getNickname() + "不在房间");
            map.put("userId", user.getUserid());
            return false;
        } else {
            /*执行准备方法*/
            boolean b = MatchingRoomP.getready(user, room);
            /*是否成功*/
            if (!b) {
                map.put("type", "SiRenPlayerReadyFailed");
                map.put("messages", "已经在位置中！");
                return false;
            }
            /*推送*/
            map.put("type", "SiRenPlayerReadySuccess");
            map.put("messages", gson.toJson(room));
            return b;
        }
    }
    /**
     * @description :四人抢庄
     * @param user
     * @param map
     * @param messages
     * @return: int
     * @date : 2019/10/12 9:38
     * @author : jj
     * @throws
     */
    public int  siRenQiangZhuang(UserBean user, Map<String, Object> map,String messages){
        /* 用户不抢庄*/
        if ("noRob".equals(messages)) {
            // 修改玩家状态
            user.setUpbanker(2);
            map.put("type", "SiRenGameInciDent");
            map.put("messages", gson.toJson(room));
            return 1;
        } else if ("rob".equals(messages)) {
            /*  调用抢庄的方法 */
            int result = operp.robBanker(user, room);
            /* 抢庄已申请*/
            if (result==1) {
                map.put("type", "SiRenGameInciDent");
                map.put("messages", gson.toJson(room));
                return 1;
            }
        }
        map.put("type", "SiRenGameInciDent");
        map.put("messages", "错误");
        return 0;
    }
    /**
     * @description :下注状态
     * @param user
     * @param map
     * @param messages
     * @return: boolean
     * @date : 2019/10/12 11:18
     * @author : jj
     * @throws
     */
    public void siRenXiaZhu(UserBean user, Map<String, Object> map,String messages){
        /*判断房间状态，判断用户状态*/
        if (user.getReady_state() != 4) {
            //庄家不下注
            if (user.getBanker() != 2) {
                map.clear();
                // 下注
                user.setPower_type(1);
                JSONObject jsonData = JSONObject.fromObject(messages);
                user.setFirst(Integer.valueOf(String.valueOf(jsonData.get("first"))));
                user.setSecond(Integer.valueOf(String.valueOf(jsonData.get("second"))));
                user.setThird(Integer.valueOf(String.valueOf(jsonData.get("third"))));
                map.put("type", "SiRenGameInciDent");
                map.put("messages", gson.toJson(room));
            }
        }
    }

//-----------------------------------------------------------------相关工具------------------------------------------------------------------------------------------
    /**
     * @description :百人小下注
     * @param user
     * @param deskno
     * @param money
     * @param sl
     * @return: java.util.HashMap<java.lang.String,java.lang.Object>
     * @date : 2019/10/11 11:20
     * @author : jj
     * @throws
     */
    public HashMap<String, Object> baiRenXiaoXz(UserBean user, String deskno, int money, HashMap<String, Object> sl){
        //判断是否为庄家
        if (user.getBanker() != 2) {
            /*判断下注位置进行下注*/
            switch (deskno) {
                case "Chu":
                    user.setChu(user.getChu() + money);
                    room.setChuMoney(room.getChuMoney() + money);
                    room.getCuserListMoney().add(money);
                    break;
                case "Tian":
                    user.setTian(user.getTian() + money);
                    room.setTianMoney(room.getTianMoney() + money);
                    room.getTuserListMoney().add(money);
                    break;
                case "Mo":
                    user.setMo(user.getMo() + money);
                    room.setMoMoney(room.getMoMoney() + money);
                    room.getMuserListMoney().add(money);
                    break;
                default:
                    break;
            }
            /**
             * 创建消息结果
             */
            user.setMoney(user.getMoney()-money);
            room.setKMoney(room.getKMoney() - money);
            sl.put("userid", user.getUserid());
            sl.put("deskno", deskno);
            sl.put("money", money);
            sl.put("userMoney",user.getMoney());
            return sl;
        }else {
            return null;
        }
    }
    /**
     * @description :百人大下注
     * @param user
     * @param deskno
     * @param money
     * @param sl
     * @return: java.util.HashMap<java.lang.String,java.lang.Object>
     * @date : 2019/10/11 12:16
     * @author : jj
     * @throws
     */
    public HashMap<String, Object> baiRenDaXz(UserBean user, String deskno, int money, HashMap<String, Object> sl){
        sl.put("money", 0);
        switch (deskno) {
            case "Chu":
                if (user.getTian() > 0 || user.getMo() > 0) {
                    break;
                } else {
                    user.setChu(user.getChu() + money);
                    room.setChuMoney(room.getChuMoney() + money);
                    room.getCuserListMoney().add(money);
                    sl.put("money", money);
                }
                break;
            case "Tian":
                if (user.getChu() > 0 || user.getMo() > 0) {
                    break;
                } else {
                    user.setTian(user.getTian() + money);
                    room.setTianMoney(room.getTianMoney() + money);
                    room.getTuserListMoney().add(money);
                    sl.put("money", money);
                }
                break;
            case "Mo":
                if (user.getChu() > 0 || user.getTian() > 0) {
                    break;
                } else {
                    user.setMo(user.getMo() + money);
                    room.setMoMoney(room.getMoMoney() + money);
                    room.getMuserListMoney().add(money);
                    sl.put("money", money);
                }
                break;
            default:
                break;
        }
        /**
         * 共享消息
         */
        sl.put("deskno", deskno);
        sl.put("userid", user.getUserid());
        sl.put("userMoney",user.getMoney());
        return sl;
    }
    /**
     * @description :相关规则
     * @return: void
     * @date : 2019/10/5 11:45
     * @author : jj
     * @throws
     */
    public void sendSz(UserBean user, Map<String, Object> map){
        RulesMoneyBean rulesMoneyBean = rulesMoneyBeanService.qyRulesMoneyBean(room.getGame_type(),room.getMoney());
        System.out.println(rulesMoneyBean);
        List<Integer> upbanker = room.getUpbanker();
        List<UserBean> userlist = new ArrayList<> ();
        List list=new ArrayList();
        HashMap mapName=new HashMap();
        if (upbanker.size()>0) {
            for (Integer integer : upbanker) {
                UserBean userBean = room.getUserBean(integer);
                userlist.add(userBean);
            }
        }
        list.add(rulesMoneyBean.getMoney1());
        list.add(rulesMoneyBean.getMoney2());
        list.add(rulesMoneyBean.getMoney3());
        list.add(rulesMoneyBean.getMoney4());
        list.add(rulesMoneyBean.getMoney5());
        mapName.put("shangzhuangRule", rulesMoneyBean.getRegulation());
        mapName.put("moneyList",list);
        mapName.put("shangzhuangUserList", userlist);
        mapName.put("roomno",room.getRoomno());
        map.put("type", "BaiRenShangZhuang");
        map.put("messages",gson.toJson(mapName));
    }

    /**
     * 是否可以开始
     * @param user
     * @param map
     * @param b
     * @return
     */
    public boolean isGameStart(UserBean user, Map<String, Object> map ,boolean b){
        /*游戏开始*/
        if (b) {
            // 判断房间中准备人数
            int zb = 0;
            for (int i = 0; i < room.getUser_positions().length; i++) {
                if (room.getUser_positions()[i] != -1) {
                    zb++;
                }
            }
            if (zb == room.getGame_userlist().size()&&zb >2) {
                /*添加对局数*/
                if (room.getGame_number() == 0) {
                    room.setGame_number(1);
                }
                // 有2个人准备（坐下）,修改房间状态
                room.setState(1);
                // 赋值房间时间.房间今日准备倒计时
                room.setTime(room.getTime01());
                map.put("type","SiRenInciDent");
                map.put("messages", gson.toJson(room));
                return true;
            }
        } else {
            if (!b) {
                map.put("type", "SiRenPlayerReadyFailed");
                map.put("messages", "您的已经在位置中，不可重复入座！");
            }
            return false;
        }
        map.put("type", "SiRenPlayerReadyFailed");
        map.put("messages", "错误");
        return false;
    }
}
